package com.cruising.backend.controller;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.cruising.backend.entity.Reports;
import com.cruising.backend.entity.Result;
import com.cruising.backend.entity.vo.PageVO;
import com.cruising.backend.entity.vo.ReportDetailVO;
import com.cruising.backend.service.ReportsService;
import com.cruising.backend.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author yezi
 * @since 2025-04-21
 */
@Slf4j
@RestController
@RequestMapping("/reports")
@CrossOrigin // 添加跨域支持
public class ReportsController {

    @Autowired
    private ReportsService reportsService;

    @Value("${aliyun.oss.endpoint}")
    private String endpoint;

    @Value("${aliyun.oss.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.oss.accessKeySecret}")
    private String accessKeySecret;

    @Value("${aliyun.oss.bucketName}")
    private String bucketName;

    // 提交举报信息
    @PostMapping("/submit/{department}")
    public Result<String> submitReport(
            @PathVariable String department,
            @RequestParam("reportType") String reportType,
            @RequestParam(value = "reporterName", required = false) String reporterName,
            @RequestParam(value = "reporterIdCard", required = false) String reporterIdCard,
            @RequestParam(value = "reporterPhone", required = false) String reporterPhone,
            @RequestParam(value = "reporterAddress", required = false) String reporterAddress,
            @RequestParam("reportedUnit") String reportedUnit,
            @RequestParam("reportedPerson") String reportedPerson,
            @RequestParam("mainIssue") String mainIssue,
            @RequestParam(value = "tags", required = false) String tags,
            @RequestParam(value = "image0", required = false) MultipartFile image0,
            @RequestParam(value = "image1", required = false) MultipartFile image1,
            @RequestParam(value = "image2", required = false) MultipartFile image2,
            @RequestParam(value = "video0", required = false) MultipartFile video0,
            @RequestParam(value = "file0", required = false) MultipartFile[] otherFiles
    ) {
        try {
            log.info("接收到举报信息提交请求，部门：{}", department);
            
            // 将部门代码转换为部门名称
            String departmentName;
            switch(department) {
                case "medical":
                    departmentName = "第一巡察组";
                    break;
                case "petition":
                    departmentName = "第二巡察组";
                    break;
                case "education":
                    departmentName = "第三巡察组";
                    break;
                default:
                    departmentName = "第一巡察组"; // 默认值
            }
            
            // 验证图片文件
            MultipartFile[] images = {image0, image1, image2};
            for (MultipartFile image : images) {
                if (image != null && !image.isEmpty()) {
                    // 检查文件类型
                    String contentType = image.getContentType();
                    if (contentType == null || !(contentType.equals("image/jpeg") || contentType.equals("image/png") || contentType.equals("image/jpg"))) {
                        return ResultUtil.fail("图片格式错误，只支持jpg、jpeg和png格式");
                    }
                    
                    // 检查文件大小，限制为10MB
                    if (image.getSize() > 10 * 1024 * 1024) {
                        return ResultUtil.fail("图片大小超过限制，最大支持10MB");
                    }
                }
            }
            
            // 验证视频文件
            if (video0 != null && !video0.isEmpty()) {
                // 检查文件类型
                String contentType = video0.getContentType();
                if (contentType == null || !contentType.equals("video/mp4")) {
                    return ResultUtil.fail("视频格式错误，只支持mp4格式");
                }
                
                // 检查文件大小，限制为50MB
                if (video0.getSize() > 50 * 1024 * 1024) {
                    return ResultUtil.fail("视频大小超过限制，最大支持50MB");
                }
            }
            
            // 验证其他文件
            if (otherFiles != null) {
                for (MultipartFile file : otherFiles) {
                    if (file != null && !file.isEmpty()) {
                        // 检查文件大小，限制为50MB
                        if (file.getSize() > 50 * 1024 * 1024) {
                            return ResultUtil.fail("文件大小超过限制，最大支持50MB：" + file.getOriginalFilename());
                        }
                    }
                }
            }
            
            // 创建举报对象
            Reports report = new Reports();
            report.setReportType(reportType);
            report.setReporterName(reporterName);
            report.setReporterIdCard(reporterIdCard);
            report.setReporterPhone(reporterPhone);
            report.setReporterAddress(reporterAddress);
            report.setReportedUnit(reportedUnit);
            report.setReportedPerson(reportedPerson);
            report.setMainIssue(mainIssue);
            report.setTags(tags);
            report.setSubmitTime(LocalDateTime.now());
            report.setDepartment(departmentName);
            
            // 处理文件上传
            MultipartFile[] videos = {video0};
            
            // 调用服务层方法保存举报信息和文件
            reportsService.saveReportWithFiles(report, images, videos, otherFiles);
            
            return ResultUtil.success("举报信息提交成功");
        } catch (Exception e) {
            log.error("提交举报信息失败", e);
            String errorMsg = "提交失败";
            
            // 根据异常类型提供更详细的错误信息
            if (e instanceof org.springframework.web.multipart.MaxUploadSizeExceededException) {
                errorMsg = "文件大小超过系统限制，请减小文件大小或分批上传";
            } else if (e.getMessage() != null && !e.getMessage().isEmpty()) {
                errorMsg += "：" + e.getMessage();
            }
            
            return ResultUtil.fail(errorMsg);
        }
    }

    //获取举报列表数据
    @GetMapping("/getReports")
    public Result<PageVO<Reports>> getNews(
            Integer pageNum,
            Integer pageSize,
            @RequestParam(required = false) String searchText,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(required = false,defaultValue = "desc") String sortType,
            @RequestParam(required = false) String types,
            @RequestParam(required = false) String labels,
            @RequestParam(required = false) String role
    ) {
        PageVO<Reports> reports = reportsService.getReports(
                pageNum, pageSize, searchText,startDate,endDate ,sortType, types,labels,role);
        return ResultUtil.success(reports);
    }

    //导出
    @GetMapping("/exportReports")
    public ResponseEntity<byte[]> exportReports(
            @RequestParam(required = false) String searchText,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(required = false,defaultValue = "desc") String sortType,
            @RequestParam(required = false) String types,
            @RequestParam(required = false) String labels,
            @RequestParam(required = false) String role
    ) throws IOException {
        log.info("开始导出举报列表Excel，参数：searchText={}, startDate={}, endDate={}, sortType={}, types={}, labels={}, role={}",
                searchText, startDate, endDate, sortType, types, labels, role);

        try {
            // 获取举报列表数据
            List<Reports> reportsList = reportsService.getReportsList(searchText, startDate, endDate, sortType, types, labels, role);
            log.info("获取到 {} 条数据", reportsList.size());

            // 创建工作簿
            try (XSSFWorkbook workbook = new XSSFWorkbook()) {
                Sheet sheet = workbook.createSheet("举报列表");

                // 设置表头样式
                CellStyle headerStyle = workbook.createCellStyle();
                headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
                headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                Font headerFont = workbook.createFont();
                headerFont.setBold(true);
                headerStyle.setFont(headerFont);

                // 创建表头
                Row headerRow = sheet.createRow(0);
                String[] header = {"举报类型", "被举报单位", "被举报人", "主要问题", "标签", "提交时间", "所属部门"};

                for (int i = 0; i < header.length; i++) {
                    Cell cell = headerRow.createCell(i);
                    cell.setCellValue(header[i]);
                    cell.setCellStyle(headerStyle);
                    sheet.autoSizeColumn(i);
                }

                // 填充数据
                int rowNum = 1;
                for (Reports report : reportsList) {
                    Row row = sheet.createRow(rowNum++);
                    row.createCell(0).setCellValue(report.getReportType());
                    row.createCell(1).setCellValue(report.getReportedUnit());
                    row.createCell(2).setCellValue(report.getReportedPerson());
                    row.createCell(3).setCellValue(report.getMainIssue());
                    row.createCell(4).setCellValue(report.getTags());
                    
                    // 设置提交时间
                    Cell submitTimeCell = row.createCell(5);
                    submitTimeCell.setCellValue(report.getSubmitTime());
                    CellStyle dateStyle = workbook.createCellStyle();
                    dateStyle.setDataFormat(workbook.createDataFormat().getFormat("yyyy-mm-dd hh:mm"));
                    submitTimeCell.setCellStyle(dateStyle);
                    
                    row.createCell(6).setCellValue(report.getDepartment());
                }

                // 写入字节数组
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                workbook.write(outputStream);
                byte[] content = outputStream.toByteArray();

                // 设置响应头
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
                String filename = URLEncoder.encode("举报列表.xlsx", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
                headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + filename);

                log.info("Excel文件生成成功，大小: {} bytes", content.length);
                return new ResponseEntity<>(content, headers, HttpStatus.OK);
            }
        } catch (Exception e) {
            log.error("导出Excel失败", e);
            throw new RuntimeException("导出Excel失败: " + e.getMessage());
        }
    }
    
    // 获取举报详情
    @GetMapping("/getReportDetail/{reportId}")
    public Result<ReportDetailVO> getReportDetail(@PathVariable Integer reportId) {
        log.info("获取举报详情，举报ID：{}", reportId);
        ReportDetailVO detailVO = reportsService.getReportDetailById(reportId);
        if (detailVO == null) {
            return ResultUtil.fail("未找到相关举报信息");
        }
        return ResultUtil.success(detailVO);
    }

    @GetMapping("/file/download")
    public ResponseEntity<byte[]> downloadFile(@RequestParam String url) {
        try {
            // 使用OSS客户端下载文件
            OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
            String objectKey = getObjectKeyFromUrl(url);
            log.info("Downloading file from OSS. ObjectKey: {}", objectKey);

            OSSObject ossObject = ossClient.getObject(bucketName, objectKey);
            byte[] content = IOUtils.toByteArray(ossObject.getObjectContent());

            // 从URL中获取文件名
            String fileName = objectKey.substring(objectKey.lastIndexOf("/") + 1);

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDisposition(ContentDisposition.builder("attachment")
                    .filename(fileName, StandardCharsets.UTF_8)
                    .build());
            headers.setCacheControl("no-cache, no-store, must-revalidate");
            headers.setPragma("no-cache");
            headers.setExpires(0);

            log.info("File downloaded successfully. Size: {} bytes", content.length);

            return ResponseEntity.ok()
                    .headers(headers)
                    .body(content);

        } catch (Exception e) {
            log.error("下载文件失败: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    // 从URL获取对象键的辅助方法
    private String getObjectKeyFromUrl(String url) {
        try {
            // 首先检查是否是完整URL
            if (url.startsWith("http")) {
                // 从完整URL中提取对象键
                String domainPart = bucketName + "." + endpoint.replace("https://", "").replace("http://", "");
                if (url.contains(domainPart)) {
                    return url.substring(url.indexOf(domainPart) + domainPart.length() + 1);
                }
            }

            // 如果不是完整URL或无法解析，尝试另一种方式
            if (url.contains("/")) {
                return url.substring(url.lastIndexOf("/") + 1);
            }

            // 如果都不成功，返回原始URL
            return url;
        } catch (Exception e) {
            log.error("提取对象键失败: {}", url, e);
            return url;
        }
    }

}
